package org.baicaixiaozhan.springbootwebdemo1.filter;

import com.google.gson.Gson;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.baicaixiaozhan.springbootwebdemo1.config.JwtConfig;
import org.baicaixiaozhan.springbootwebdemo1.domain.User;
import org.baicaixiaozhan.springbootwebdemo1.service.UserService;
import org.baicaixiaozhan.springbootwebdemo1.util.HttpUtils;
import org.baicaixiaozhan.springbootwebdemo1.util.IOUtils;
import org.baicaixiaozhan.springbootwebdemo1.util.JWTUtils;
import org.baicaixiaozhan.springbootwebdemo1.vo.UsernameAndPasswordAuthenticationRequest;
import org.springframework.core.annotation.Order;

import javax.crypto.SecretKey;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Reader;

/**
 * 专门对登录接口的过滤处理
 *
 * @author baicaixiaozhan
 * @since 2021/1/29
 */
@Order(1)
@WebFilter(urlPatterns = "/api/login")
@Slf4j
@AllArgsConstructor
public class JwtUsernameAndPasswordAuthenticationFilter implements Filter {

    private final UserService userService;
    private final JwtConfig jwtConfig;
    private final SecretKey secretKey;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        Reader targetReader = IOUtils.convertToReader(request.getInputStream());

        UsernameAndPasswordAuthenticationRequest usernameAndPasswordAuthenticationRequest = new Gson()
                .fromJson(targetReader, UsernameAndPasswordAuthenticationRequest.class);

        targetReader.close();
        try {
            User user = userService.authenticate(usernameAndPasswordAuthenticationRequest);
            String token = JWTUtils.generatorToken(user, secretKey, jwtConfig);
            HttpUtils.setCurrentLoginUser(user);
            response.setHeader("authorization", token);
        } catch (Exception e) {
            request.setAttribute("filter.exception", e);
            request.getRequestDispatcher("/filter/exception")
                    .forward(request, response);
        }

        filterChain.doFilter(request, response);
    }
}
